package com.cb.service.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.cb.config.AlipayConfig;
import com.cb.dao.ConductorDao;
import com.cb.dao.ConductorVipDao;
import com.cb.pojo.*;
import com.cb.service.ConductorService;
import com.github.pagehelper.PageHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static java.lang.String.valueOf;
import static java.util.concurrent.TimeUnit.SECONDS;

@Service
public class ConductorServiceImpl implements ConductorService {

    @Autowired
    private ConductorDao conductorDao;

    @Autowired
    private ConductorVipDao conductorVipDao;

    Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

    /**
     * 添加售票员:注册
     * */
    @Override
    public int conductorInsert(HashMap map) {

        String md5Password = DigestUtils.md5DigestAsHex(String.valueOf(map.get("password")).getBytes());
        Employee conductor = new Employee();
        conductor.setUsername(String.valueOf(map.get("username")))
                .setPassword(md5Password)
                .setYyid(String.valueOf(map.get("yyid")))
                .setYyname(String.valueOf(map.get("yyname")))
                .setStatus(String.valueOf(map.get("status")));
        if(conductorDao.conductorInsert(conductor)==1){
            return 1;
        }
        else{
            return 0;
        }
    }

    /**
     * 售票员登录（count，pwd）
     * */
    @Override
    public String login(HashMap json) {
        String count = String.valueOf(json.get("account"));
        String pwd = DigestUtils.md5DigestAsHex(String.valueOf(json.get("password")).getBytes());
        Employee user = conductorDao.selectCount(count);
        AdministratorInfomation userinfo = new AdministratorInfomation();
        if (user != null){
            if (user.getPassword().equals(pwd)){
                String yyid = user.getYyid();
                Cinema cinema = conductorDao.selectCinema(yyid);
                if (cinema != null){
                    userinfo.setUsername(user.getUsername())
                            .setYyid(user.getYyid()).setYyname(user.getYyname()).setStatus(user.getStatus())
                            .setCity(cinema.getCity()).setVipdiscount(cinema.getVipdiscount())
                            .setPaymentaccount(cinema.getPaymentaccount()).setVipprice(cinema.getVipprice());
                    String userJson = JSON.toJSONString(userinfo);
                    return userJson;
                }
                else{
                    return "null_cinema";
                }
            }
            else{
                return "pwd_error";
            }
        }
        else {
            return "account_error";
        }
    }

    @Override
    public String getOrder(HashMap map) {
        int pageNum = Integer.parseInt(String.valueOf(map.get("page")));
        int pageSize = Integer.parseInt(String.valueOf(map.get("size")));
        PageHelper.startPage(pageNum, pageSize);
        List<OrderList> orderLists = conductorDao.getOrder(map);
        String json = JSON.toJSONString(orderLists);
        return json;
    }

    @Autowired
    @Qualifier("redisTemplateCustomize")
    private RedisTemplate<Object, Object> redisCacheTemplate;

    private String allOrderListRedis = "allOrderListRedis";

    @Override
    public String addMemberShip(HashMap json, HttpServletRequest requests) throws AlipayApiException, ParseException {

        String username = String.valueOf(json.get("username"));
        //String id = String.valueOf(session.getAttribute("zzid"));
        String id = username;
        String yyid = String.valueOf(json.get("yyid"));
        id += yyid + System.currentTimeMillis();
        double vipprice = conductorDao.selectVipPrice(yyid);///要新增

        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.sign_type);
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();

        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(id);
        model.setSubject(yyid);
        model.setTotalAmount(String.valueOf(vipprice));
        model.setBody("会员");
        model.setTimeoutExpress("2m");
        //model.setProductCode(String.valueOf(session.getAttribute("zzid")));
        model.setProductCode(username);

        request.setBizModel(model);
        request.setNotifyUrl(AlipayConfig.notify_url);
        request.setReturnUrl(AlipayConfig.return_url);
        String form = alipayClient.pageExecute(request).getBody();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date endtime = null;
        if (conductorDao.selectEndTime(yyid, username) == null) {
            endtime = null;
        }
        else{
            endtime = conductorDao.selectEndTime(yyid, username);
        }
        String now = df.format(new Date());
        Date nowDate = df.parse(now);
        Date begin = null, end = null;
        int flag = 0;
        if (endtime == null) {
            flag = -1;
        } else {
            flag = endtime.compareTo(nowDate);
        }
        logger.info(String.format("flag: %s",flag));
        if (flag == 1) {
            begin = conductorDao.selectbegin(yyid,username);
            Calendar cal = Calendar.getInstance();
            cal.setTime(endtime);
            cal.add(Calendar.DATE,30);
            end = cal.getTime();
        } else {
            begin = nowDate;
            Calendar cal = Calendar.getInstance();
            cal.setTime(begin);
            cal.add(Calendar.DATE,30);
            end = cal.getTime();
        }
        if (endtime == null){
            conductorDao.insertVip(yyid,username,df.parse(df.format(begin)),df.parse(df.format(end)));
        }
        else {
            conductorDao.updateuservip(yyid, username, df.parse(df.format(begin)),df.parse(df.format(end)));
        }
        return form;
    }

    @Override
    public String scheduled(HashMap json, HttpServletRequest request) throws ParseException {
        OrderList orderList = new OrderList();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = df.format(new Date());

        String username = String.valueOf(json.get("username"));
        User user = conductorDao.selectUser(username);
        String ypid = String.valueOf(json.get("ypid"));
        double price = conductorDao.selectFilmPrice(ypid);

        int tfvip;
        String now = df.format(new Date());
        Date nowDate = df.parse(now);
        Date endDate = conductorDao.selectEndVipTime(String.valueOf(json.get("username")));
        if (endDate == null || nowDate.getTime()>endDate.getTime()){
            tfvip = 0;
        }
        else{
            tfvip = 1;
        }
        orderList.setYyid(String.valueOf(json.get("yyid")))
                .setYyname(String.valueOf(json.get("yyname")))
                .setYpid(String.valueOf(json.get("ypid")))
                .setYpname(String.valueOf(json.get("ypname")))
                .setCcid(String.valueOf(json.get("ccid")))
                .setUsername(username)
                .setName("售票处购买")
                .setPrice(Double.valueOf(String.valueOf(price)))
                .setTfvip(tfvip)
                .setRefundfee(0.0)
                .setChangefee(0.0)
                .setStatus("已支付")
                .setStatustime(df.parse(date))
                .setCreatetime(df.parse(date))
                .setLocate(String.valueOf(json.get("locate")));
        String id = "SX"+System.currentTimeMillis()+String.valueOf(json.get("ypid"));
        for (int i=0;i<10;i++){
            if (orderList.getUsername().charAt(i)=='@' && i!=9){
                for (int j=0 ;j<10-i-1;j++){
                    id+="0";
                }
                break;
            }
            id+=String.valueOf(orderList.getUsername().charAt(i));
        }
        System.out.println(id);
        orderList.setId(id);

        //double price = orderList.getPrice();
        if (orderList.getTfvip()==1){
            double amount = conductorDao.selectamount(orderList.getUsername());
            double discount = conductorDao.selectDiscount(orderList.getYyid());
            List<Integer> list = conductorDao.selectgrade();
            int grade = 0;
            for (int i=0;i<list.size()-1;i++){
                if (amount>=list.get(i) && amount<list.get(i+1)){
                    grade=i+1;
                    break;
                }
            }
            price = price - price*(discount*grade);
            orderList.setPrice(price);
        }
        redisCacheTemplate.opsForValue().set(id,orderList,300,SECONDS);
        String jsons = JSON.toJSONString(orderList);
        return jsons;
    }

    @Override
    public String filmPly(HashMap json, HttpServletRequest requests) throws ParseException,AlipayApiException {
        String ddid = String.valueOf(json.get("ddid"));
        OrderList orderList = (OrderList) redisCacheTemplate.opsForValue().get(ddid);
        conductorDao.insertOrderList(orderList);
        String ccid = orderList.getCcid();
        String locate = orderList.getLocate();
        ScreeninFormation screeninFormation = conductorDao.selectscreeninFormation(ccid);
        int number = conductorDao.selectnumber(screeninFormation.getYyid(),screeninFormation.getNumberid());
        int x = Integer.parseInt(String.valueOf((int)Math.sqrt(Double.valueOf(number))));
        int y=x;
        String list = conductorDao.selectList(Integer.parseInt(ccid));
        if(list==null){
            int[][] str = new int[x][y];
            int num=0;
            int x1=0,y1=-1;
            for (int i=0;i<locate.length();i++){
                if (locate.charAt(i)>='0'&&locate.charAt(i)<='9'){
                    num++;
                    y1++;
                    if (num>x && num%x==1){
                        x1++;
                    }
                    if (locate.charAt(i)!='0') {
                        str[x1][y1 % x] = Integer.parseInt(String.valueOf(locate.charAt(i)));
                    }
                }
            }
            String jsons = JSON.toJSONString(str);
            int i = conductorDao.updateList(Integer.parseInt(ccid),jsons);
        }
        else{
            int[][] str = new int[x][y];
            List<Integer> list1 = new ArrayList<>();
            for (int i=0;i<list.length();i++){
                if (list.charAt(i)>='0'&& list.charAt(i)<='9'){
                    list1.add(Integer.parseInt(String.valueOf(list.charAt(i))));
                }
            }
            //越界处理
            list1.add(0);
            int flag=0;
            for (int i=0;i<x;i++){
                for (int j=0;j<y;j++){
                    str[i][j]=list1.get(flag);
                    flag++;
                }
            }
            int num=0;
            int x1=0,y1=-1;
            for (int i=0;i<locate.length();i++){
                if (locate.charAt(i)>='0'&&locate.charAt(i)<='9'){
                    num++;
                    y1++;
                    if (num>x && num%x==1){
                        x1++;
                    }
                    if (locate.charAt(i)!='0') {
                        str[x1][y1 % x] = Integer.parseInt(String.valueOf(locate.charAt(i)));
                    }
                }
            }
            String jsons = JSON.toJSONString(str);
            int i = conductorDao.updateList(Integer.parseInt(ccid),jsons);
        }
        insertOrderlistRedis(orderList);
        return zhiFu(orderList.getId(),orderList.getYpname(),String.valueOf(orderList.getPrice()),"电影","2m",orderList.getYyid());
    }

    public void insertOrderlistRedis(OrderList orderList){
        AllOrderListRedis allOrderListRedis = new AllOrderListRedis();
        allOrderListRedis.setYpid(orderList.getYpid())
                .setYpname(orderList.getYpname());
        if (redisCacheTemplate.opsForZSet().size("allOrderListRedis")==null){
            allOrderListRedis.setNumber(1);
            conductorDao.insertAllOrderListRedis(allOrderListRedis);
            redisCacheTemplate.opsForZSet().add("allOrderListRedi",orderList.getYpname(),1);
        }
        else{
            double score =0;
            if(redisCacheTemplate.opsForZSet().score("allOrderListRedi",orderList.getYpname()) == null){
                score = 0;
            }
            else{
                score = Double.parseDouble(String.valueOf(redisCacheTemplate.opsForZSet().score("allOrderListRedi",orderList.getYpname())));
            }
            if (score==0){
                allOrderListRedis.setNumber(1);
                conductorDao.insertAllOrderListRedis(allOrderListRedis);
                redisCacheTemplate.opsForZSet().add("allOrderListRedi",orderList.getYpname(),1);
            }
            else{
                allOrderListRedis.setNumber((int)(score+1));
                conductorDao.updateAllOrderListRedis(allOrderListRedis);
                redisCacheTemplate.opsForZSet().add("allOrderListRedi",orderList.getYpname(),score+1);
            }
        }
    }

    @Override
    public String zhiFu(String OutTradeNo,String Subject,String TotalAmount,String Body,String TimeoutExpress,String ProductCode) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.sign_type);
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();

        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(OutTradeNo);
        model.setSubject(Subject);
        model.setTotalAmount(TotalAmount);
        model.setBody(Body);
        model.setTimeoutExpress(TimeoutExpress);
        model.setProductCode(ProductCode);
        request.setBizModel(model);
        request.setNotifyUrl(AlipayConfig.notify_url);
        request.setReturnUrl(AlipayConfig.return_url);
        String form  = alipayClient.pageExecute(request).getBody();
        return form;
    }

    @Override
    public String refund(String id, double price, double discount) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.sign_type);
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
        String refund_amount = String.valueOf(price * discount);
        String out_request_no = new String(UUID.randomUUID().toString());
        alipayRequest.setBizContent("{\"out_trade_no\":\"" + id + "\","
                + "\"refund_amount\":\"" + refund_amount + "\","
                + "\"out_request_no\":\"" + out_request_no + "\"}");
        String result = alipayClient.execute(alipayRequest).getBody();
        return result;
    }

    /**
     * 退款
     *
     * @param json
     * @param request
     * @return
     * @throws ParseException
     * @throws AlipayApiException
     */
    @Override
    public String userrefund(HashMap json, HttpServletRequest request) throws ParseException, AlipayApiException {
        String ddid = valueOf(json.get("ddid"));
        OrderList orderList = conductorDao.refund(ddid);
        Date time = conductorDao.selectDdidTime(orderList.getCcid());
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String now = df.format(new Date());
        Date nowtime = df.parse(now);
        String time1 = df.format(time);
        Date kstime = df.parse(time1);
        Date bjtime = null;
        Calendar c = Calendar.getInstance();
        c.set(Calendar.HOUR_OF_DAY, (c.get(Calendar.HOUR_OF_DAY) - 3));
        bjtime = c.getTime();
        int a = bjtime.compareTo(nowtime);
        if (a < 0) {
            Date bjtime1 = null;
            c.set(Calendar.HOUR_OF_DAY, (c.get(Calendar.HOUR_OF_DAY) - 4));
            bjtime1 = c.getTime();
            int a1 = bjtime1.compareTo(nowtime);
            if (a1 < 0) {
                String form = refund(orderList.getId(), orderList.getPrice(), 1.0);
            } else {
                String form = refund(orderList.getId(), orderList.getPrice(), 0.9);
            }
        }
        String form = refund(orderList.getId(), orderList.getPrice(), 0.7);
        if (conductorDao.updateOrderList("已退票",ddid)==1){
            return JSON.toJSONString("退票成功"+form);
        }
        else{
            return JSON.toJSONString("退票失败");
        }
    }

    /**
     * 判断是不是可以改签
     *
     * @param json
     * @param request
     * @return
     * @throws ParseException
     */
    @Override
    public String changeOrder(HashMap json, HttpServletRequest request) throws ParseException {
        String ddid = String.valueOf(json.get("ddid"));
        HttpSession session = request.getSession();
        session.setAttribute("ddid", ddid);
        OrderList orderList = conductorDao.refund(ddid);
        Date time = conductorDao.selectDdidTime(orderList.getCcid());
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String now = df.format(new Date());
        Date nowtime = df.parse(now);
        //Date bjtime = null;
        //bjtime.setHours(time.getHours()-3);
        int a = time.compareTo(nowtime);
        if (a > 0) {
            List<ScreeninFormation> list = conductorDao.yyidSelectsi(orderList.getYyid(), nowtime, null);
            return JSON.toJSONString(list);
        } else {
            return "电影即将开始无法改签";
        }
    }

    /**
     * 确定改签
     *
     * @param json
     * @param request
     * @return
     * @throws ParseException
     * @throws AlipayApiException
     */
    @Override
    public String qrChangeOrder(HashMap json, HttpServletRequest request) throws ParseException, AlipayApiException {

        //id是放映信息的id
        String id = String.valueOf(json.get("id"));
        String locate = String.valueOf(json.get("locate"));
        String ddid = String.valueOf(json.get("ddid"));
        OrderList orderList = conductorDao.refund(ddid);
        Date time = conductorDao.selectDdidTime(orderList.getCcid());
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String now = df.format(new Date());
        Date nowtime = df.parse(now);
        Date bjtime = null;
        Calendar c = Calendar.getInstance();
        c.set(Calendar.HOUR_OF_DAY, (c.get(Calendar.HOUR_OF_DAY) - 3));
        bjtime = c.getTime();
        int a = bjtime.compareTo(nowtime);
        int flag = 0;
        //改签支付手续费
        if (a < 0) {
            Date bjtime1 = null;
            c.set(Calendar.HOUR_OF_DAY, (c.get(Calendar.HOUR_OF_DAY) - 4));
            bjtime1 = c.getTime();
            int b = bjtime1.compareTo(nowtime);
            if (b < 0) {
                flag = conductorDao.updateOrderLists(id, "改签", nowtime, 0, ddid);
            } else {
                double refundfee = orderList.getPrice() * 0.05;
                zhiFu(ddid, orderList.getYpname(), String.valueOf(refundfee), "电影票", "5m", "code");
                flag = conductorDao.updateOrderLists(id, "改签", nowtime, 0, ddid);
            }
        } else {
            double refundfee = orderList.getPrice() * 0.15;
            zhiFu(ddid, orderList.getYpname(), String.valueOf(refundfee), "电影票", "5m", "code");
            flag = conductorDao.updateOrderLists(id, "改签", nowtime, 0, ddid);
        }

        //对新的场次做选座
        int number = conductorDao.selectnumber(orderList.getYyid(), Integer.parseInt(id));
        int x = Integer.parseInt(String.valueOf(Math.sqrt(Double.valueOf(number))));
        int y = x;
        String list = conductorDao.selectList(Integer.parseInt(id));
        if (list == null) {
            String[][] str = new String[x][y];
            int num = 0;
            int x1 = 0, y1 = 0;
            for (int i = 0; i < locate.length(); i++) {
                if (locate.charAt(i) >= '0' && locate.charAt(i) <= '9') {
                    if (num % 2 == 0) {
                        x1 = Integer.parseInt(String.valueOf(locate.charAt(i)));
                    } else {
                        y1 = Integer.parseInt(String.valueOf(locate.charAt(i)));
                    }
                    num++;
                }
                if (num % 2 == 0 && num != 0) {
                    str[x1 - 1][y1 - 1] = "1";
                }
            }
            String jsons = JSON.toJSONString(str);
            int i = conductorDao.updateList(Integer.parseInt(id), jsons);
        } else {
            String[][] str = new String[x][y];
            List<Integer> list1 = new ArrayList<>();
            for (int i = 0; i < list.length(); i++) {
                if (list.charAt(i) == '0' || list.charAt(i) == '1') {
                    list1.add(Integer.parseInt(String.valueOf(list.charAt(i))));
                }
            }
            //越界处理
            list1.add(0);
            int flag1 = 0;
            for (int i = 0; i < x; i++) {
                for (int j = 0; j < y; j++) {
                    str[i][j] = String.valueOf(list1.get(flag1));
                    flag1++;
                }
            }
            int num = 0;
            int x1 = 0, y1 = 0;
            for (int i = 0; i < locate.length(); i++) {
                if (locate.charAt(i) >= '0' && locate.charAt(i) <= '9') {
                    if (num % 2 == 0) {
                        x1 = Integer.parseInt(String.valueOf(locate.charAt(i)));
                    } else {
                        y1 = Integer.parseInt(String.valueOf(locate.charAt(i)));
                    }
                    num++;
                }
                if (num % 2 == 0 && num != 0) {
                    str[x1 - 1][y1 - 1] = "1";
                }
            }
            String jsons = JSON.toJSONString(str);
            int i = conductorDao.updateList(Integer.parseInt(id), jsons);
        }
        if (flag == 0) {
            return "改签失败";
        } else {
            return "改签成功";
        }
    }

}
